# -*- coding: utf-8 -*-
# created on 2016/11/30
from mathsolver.functions.shulie.ShuLie_getVariable import ShuLieGetVariable
from mathsolver.functions.base import *
from mathsolver.functions.shulie.Fundamental import sl_shulie_name
from mathsolver.functions.shulie.ShuLie_getSeqPoly import ShuLieGetSeqPoly


class ShuLieDengBiProve001(BaseFunction):
    """
    已知数列{a_{n}}满足a_{1}=1,a_{n+1}=3a_{n}+1.证明{a_{n}+\\frac{1}{2}}是等比数列.
    """
    def solver(self, *args):
        seq = args[0].sympify()
        stepsolver = ShuLieGetSeqPoly(self.known).solver(args[0])
        self.steps += stepsolver.steps
        self.label.update(stepsolver.label)
        seq_values = stepsolver.output[0].sympify()
        for seq_value in seq_values:
            fn = seq_value
            fn1 = fn.subs({sympify('n'): sympify('n+1')})
            q = (fn1 / fn).expand().simplify()
            if sympify('n') not in q.free_symbols:
                self.steps.append(["", "∴%s是等比数列" % (new_latex(seq))])
        self.label.add("定义法证明等比数列")
        return self


class ShuLieDengBiProve002(BaseFunction):
    def solver(self, *args):
        if len(args) != 1:
            raise Exception('Try Error!')
        if not isinstance(args[0], BaseSequence):
            raise Exception('Try Error!')
        seq = args[0].sympify()
        known = self.known
        if 'Sequations' not in known:
            raise Exception('Try Error!')
        if not known['Sequations']:
            raise Exception('Try Error!')
        seqs = known['Sequations']
        new_seqs = []
        new_other_seqs = []
        for eq in seqs:
            if len(eq) == 2:
                expr = (eq[0] - eq[1]).expand().simplify()
            else:
                expr = (eq[0] - eq[2]).expand().simplify()
            expr_xiangs = sl_shulie_name(expr)
            flag = []
            if not expr_xiangs:
                flag.append(0)
            else:
                for xiang in expr_xiangs:
                    sl = self.search(str(xiang))
                    if sl:
                        flag.append(0)
                    else:
                        flag.append(1)
            if sum(flag) >= 1:
                new_other_seqs.append(eq)
            else:
                new_seqs.append(eq)
        known['Sequations'] = new_seqs
        if not new_other_seqs:
            raise Exception('Try Error!')
        if len(new_other_seqs) != 1:
            raise Exception('Try Error!')
        try:
            answer = solve(new_other_seqs[0][0] - new_other_seqs[0][1], seq)[0]
        except Exception:
            raise Exception('Try Error!')
        try:
            stepsolver = ShuLieGetVariable(known).solver(BasePoly(answer))
            self.steps += stepsolver.steps
            self.label.update(stepsolver.label)
            tongxiangs = stepsolver.output[0].sympify()
            for TongXiang in tongxiangs:
                self.steps.append(["", "%s = %s" % (new_latex(seq), new_latex(TongXiang))])
                gongbi = TongXiang.subs({sympify('n'): sympify('n') + 1}) / TongXiang
                gongbi = gongbi.expand().simplify()
                if sympify('n') not in gongbi.free_symbols:
                    self.steps.append(["", "%s是等比数列" % (new_latex(seq))])
            return self
        except Exception:
            raise Exception('Try Error!')


class ShuLieDengBiProve(BaseFunction):
    CLS = [ShuLieDengBiProve001]

    def solver(self, *args):
        known = self.known
        r = None
        for cl in ShuLieDengBiProve.CLS:
            try:
                new_known = dict(known)
                r = cl(new_known, verbose=True).solver(*args)
                break
            except Exception:
                pass
        if not r:
            raise 'try fail'
        return r
